<script setup>
import { ref, computed, onMounted } from 'vue'
import { getVariablesList, getCategoriesList } from '@/api/data'
import { ElMessage } from 'element-plus'
import { Plus, Minus } from '@element-plus/icons-vue'

// 1. 构建树形结构
function buildTree(list, parentId = 0) {
  return list
    .filter(item => item.parentId === parentId)
    .map(item => ({
      ...item,
      children: buildTree(list, item.id)
    }))
}
const tree = ref([])
const variableList = ref([])
const flatCategoryList = ref([]) // 新增
const treeLoading = ref(false)

// 2. 选中节点
const selectedNode = ref(null)
function handleNodeClick(node) {
  // 叶子节点：有公式且parentId不为0
  if (
    (node.consumptionDataType || node.valueAddedDatatype) &&
    node.parentId !== 0
  ) {
    selectedNode.value = node
    // 解析变量
    parseVariables(node)
  } else {
    selectedNode.value = null
    inputVars.value = {}
    variables.value = []
  }
}

// 3. 解析公式变量
const variables = ref([])
const inputVars = ref({})
function parseVariables(node) {
  // 合并所有公式字符串
  let formula = ''
  if (node.consumptionDataType) formula += node.consumptionDataType + ','
  if (node.valueAddedDatatype) formula += node.valueAddedDatatype
  // 匹配变量名
  const varSet = new Set(
    Array.from(formula.matchAll(/\b[a-zA-Z]+\b/g)).map(m => m[0])
  )
  // 过滤掉数字和js关键字
  const jsKeywords = ['if', 'else', 'return', 'Math']
  const filtered = Array.from(varSet).filter(
    v => isNaN(Number(v)) && !jsKeywords.includes(v)
  )
  // 变量中文名和单位
  variables.value = filtered.map(v => {
    const found = variableList.value.find(item => item.variable === v)
    return {
      key: v,
      label: found?.description || v,
      unit: found?.unit || '',
      needAdd: found?.needAdd || false
    }
  })
  // 初始化输入
  inputVars.value = Object.fromEntries(filtered.map(v => {
    const found = variableList.value.find(item => item.variable === v)
    return [v, found?.needAdd ? [''] : '']
  }))
}

function handleAddVar(key) {
  inputVars.value[key].push('')
}
function handleRemoveVar(key, idx) {
  if (inputVars.value[key].length > 1) {
    inputVars.value[key].splice(idx, 1)
  }
}

// 适配：两个特殊变量key
const DOUBLE_ADD_KEYS = ['dq', 'um']

function showDoubleAddBtn() {
  // 检查这两个变量都存在且needAdd
  const keys = DOUBLE_ADD_KEYS
  const foundVars = keys.map(k => variables.value.find(v => v.key === k && v.needAdd))
  return foundVars.every(Boolean)
}
function handleDoubleAdd() {
  DOUBLE_ADD_KEYS.forEach(k => {
    inputVars.value[k].push('')
  })
}

function handleDoubleRemove(idx) {
  DOUBLE_ADD_KEYS.forEach(k => {
    if (inputVars.value[k].length > 1) {
      inputVars.value[k].splice(idx, 1)
    }
  })
}

onMounted(async () => {
  treeLoading.value = true
  try {
    // 获取分类数据
    const categoriesRes = await getCategoriesList()
    flatCategoryList.value = categoriesRes.data // 新增
    tree.value = buildTree(categoriesRes.data)
    // 获取变量数据
    const variablesRes = await getVariablesList()
    console.log(variablesRes);
    
    variableList.value = variablesRes.rows
  } finally {
    treeLoading.value = false
  }
})

// 4. 地区、服务类型、纳税人类型
const area = ref('市区')
const stampType = ref('销售货物')
const taxpayerType = ref('一般纳税人') // 新增纳税人类型

// 5. 印花税类型与税率
const stampOptions = [
  { label: '销售货物/建筑服务/运输服务/承揽服务/技术服务', value: '销售货物', rate: 0.0003 },
  { label: '租赁服务/仓储服务/财产保险服务', value: '租赁服务', rate: 0.001 }
]
const areaOptions = [
  { label: '市区', value: '市区', rate: 0.07 },
  { label: '县城和镇', value: '县城和镇', rate: 0.03 },
  { label: '其他地区', value: '其他地区', rate: 0.01 }
]

// 6. 计算结果
const result = ref(null)
const resultFormulas = ref([]) // 新增：存储每个税种的公式
function getVarLabel(key) {
  const found = variableList.value.find(item => item.variable === key)
  return found ? found.description : key
}
function replaceVarsWithLabel(formula) {
  // 替换变量为中文
  return formula.replace(/\b[a-zA-Z]+\b/g, v => getVarLabel(v))
}
function replaceVarsWithValue(formula, vars) {
  // 替换变量为输入值，数值保留两位小数
  return formula.replace(/\b[a-zA-Z_]+\b/g, v => {
    if (vars[v] !== undefined) {
      const val = vars[v]
      if (typeof val === 'number') return val.toFixed(2)
      if (typeof val === 'string' && val !== '') return Number(val).toFixed(2)
      return val
    }
    return v
  })
}
function calc() {
  try {
    resultFormulas.value = [] // 清空
    // 变量赋值
    const vars = { ...inputVars.value }
    for (const v of variables.value) {
      if (v.needAdd && !DOUBLE_ADD_KEYS.includes(v.key)) {
        vars[v.key] = (Array.isArray(vars[v.key]) ? vars[v.key] : []).reduce((sum, val) => sum + Number(val || 0), 0)
      }
    }
    if (vars.dq && vars.um && Array.isArray(vars.dq) && Array.isArray(vars.um)) {
      vars['dq_um_sum'] = vars.dq.reduce((sum, dqVal, idx) => {
        const umVal = Number(vars.um[idx] || 0)
        return sum + Number(dqVal || 0) * umVal
      }, 0)
    } else {
      vars['dq_um_sum'] = (Number(vars.dq) || 0) * (Number(vars.um) || 0)
    }
    // 公式计算
    let consumptionTax = 0
    let valueAddedTax = 0
    let consumptionFormulaRaw = ''
    let consumptionFormulaVal = ''
    let valueAddedFormulaRaw = ''
    let valueAddedFormulaVal = ''
    if (selectedNode.value.consumptionDataType) {
      let formula = selectedNode.value.consumptionDataType.replace(/dq\s*\*\s*um/g, 'dq_um_sum')
      consumptionFormulaRaw = replaceVarsWithLabel(selectedNode.value.consumptionDataType)
      consumptionFormulaVal = replaceVarsWithValue(formula, vars)
      consumptionTax = evalFormula(formula, vars)
    }
    if (selectedNode.value.valueAddedDatatype) {
      let vatObj = {};
      try {
        const jsonLike = selectedNode.value.valueAddedDatatype
          .replace(/([\w\u4e00-\u9fa5]+)\s*:/g, '"$1":')
          .replace(/'([^']*)'/g, '"$1"');
        vatObj = JSON.parse(jsonLike);
      } catch (e) {
        vatObj = { '一般纳税人': selectedNode.value.valueAddedDatatype };
      }
      let vatStr = vatObj[taxpayerType.value || taxpayerType] || '';
      valueAddedFormulaRaw = replaceVarsWithLabel(vatStr)
      let vatStrEval = vatStr.replace(/dq\s*\*\s*um/g, 'dq_um_sum')
      valueAddedFormulaVal = replaceVarsWithValue(vatStrEval, vars)
      valueAddedTax = evalFormula(vatStrEval, vars);
    }
    // 城建税
    const areaRate = areaOptions.find(a => a.value === area.value).rate
    const cityTax = (valueAddedTax + consumptionTax) * areaRate
    // 教育费附加
    const eduTax = (valueAddedTax + consumptionTax) * 0.03
    // 地方教育附加
    const localEduTax = (valueAddedTax + consumptionTax) * 0.02
    // 印花税
    const stampRate = stampOptions.find(s => s.value === stampType.value).rate
    const price = Number(vars.u) || 0
    const count = Number(vars.s) || Number(vars.num) || 0
    const stampTax = price * count * stampRate
    // 单位成本
    const cost = Number(vars.cost) || 0
    // 税后盈利
    const profit =
      price * count -
      cost * count -
      valueAddedTax -
      consumptionTax -
      cityTax -
      eduTax -
      localEduTax -
      stampTax
    // 记录公式
    resultFormulas.value = [
      {
        label: '增值税',
        raw: valueAddedFormulaText.value || valueAddedFormulaRaw,
        val: valueAddedFormulaVal,
        result: valueAddedTax
      },
      {
        label: '消费税',
        raw: consumptionFormulaText.value || consumptionFormulaRaw,
        val: consumptionFormulaVal,
        result: consumptionTax
      },
      {
        label: '城建税',
        raw: '（增值税+消费税）* 城区税率',
        val: `(${valueAddedTax.toFixed(2)}+${consumptionTax.toFixed(2)})*${areaRate}`,
        result: cityTax
      },
      {
        label: '教育费附加',
        raw: '（增值税+消费税）* 3%',
        val: `(${valueAddedTax.toFixed(2)}+${consumptionTax.toFixed(2)})*0.03`,
        result: eduTax
      },
      {
        label: '地方教育附加',
        raw: '（增值税+消费税）* 2%',
        val: `(${valueAddedTax.toFixed(2)}+${consumptionTax.toFixed(2)})*0.02`,
        result: localEduTax
      },
      {
        label: '印花税',
        raw: '单价*数量*印花税率',
        val: `${price}*${count}*${stampRate}`,
        result: stampTax
      },
      {
        label: '税后盈利',
        raw: '单价*数量-单位成本*数量-增值税-消费税-城建税-教育费附加-地方教育附加-印花税',
        val: `${price}*${count}-${cost}*${count}-${valueAddedTax.toFixed(2)}-${consumptionTax.toFixed(2)}-${cityTax.toFixed(2)}-${eduTax.toFixed(2)}-${localEduTax.toFixed(2)}-${stampTax.toFixed(2)}`,
        result: profit
      }
    ]
    result.value = {
      valueAddedTax,
      consumptionTax,
      cityTax,
      eduTax,
      localEduTax,
      stampTax,
      profit
    }
  } catch (e) {
    console.log(e);
    ElMessage.error('计算出错，请检查输入')
  }
}

// 7. 公式安全计算
function evalFormula(formula, vars) {
  // 替换变量
  let expr = formula
  for (const [k, v] of Object.entries(vars)) {
    expr = expr.replaceAll(new RegExp(`\\b${k}\\b`, 'g'), v || 0)
  }
  // 只允许数字、运算符、小数点、括号
  if (!/^[\d\.\+\-\*\/\(\)\s]+$/.test(expr)) throw new Error('非法公式')
  // eslint-disable-next-line no-eval
  return eval(expr)
}

// 递归获取节点路径
function getNodePath(node, list, path = []) {
  if (!node) return path;
  path.unshift(node.name);
  const parent = list.find(item => item.id === node.parentId);
  if (parent) {
    return getNodePath(parent, list, path);
  }
  return path;
}
const nodePath = computed(() => {
  if (!selectedNode.value) return [];
  // 用原始一维数据
  return getNodePath(selectedNode.value, flatCategoryList.value);
});

// 新增：获取公式文本（根据纳税人类型）
const consumptionFormulaText = computed(() => {
  if (!selectedNode.value || !selectedNode.value.consumptionCumpte) return '';
  let val = selectedNode.value.consumptionCumpte;
  // 尝试解析伪json
  if (typeof val === 'string' && val.trim().startsWith('{')) {
    try {
      const jsonLike = val
        .replace(/([\\w\\u4e00-\\u9fa5]+)\\s*:/g, '\"$1\":')
        .replace(/'([^']*)'/g, '\"$1\"');
      const obj = JSON.parse(jsonLike);
      // 取第一个 value
      return Object.values(obj)[0] || '';
    } catch (e) {
      return val;
    }
  }
  return val;
});
const valueAddedFormulaText = computed(() => {
  if (!selectedNode.value || !selectedNode.value.valueAddedCumpte) return '';
  let obj = {};
  try {
    const jsonLike = selectedNode.value.valueAddedCumpte
      .replace(/([\w\u4e00-\u9fa5]+)\s*:/g, '"$1":')
      .replace(/'([^']*)'/g, '"$1"');
    obj = JSON.parse(jsonLike);
  } catch (e) {
    obj = { '一般纳税人': selectedNode.value.valueAddedCumpte };
  }
  let formula = obj[taxpayerType.value || taxpayerType] || '';
  // 检查 dq/um 是否有多组
  if (
    inputVars.value.dq &&
    inputVars.value.um &&
    Array.isArray(inputVars.value.dq) &&
    inputVars.value.dq.length > 1
  ) {
    // 构造 ∑（...）内容
    const sumItems = inputVars.value.dq.map((dqVal, idx) => {
      const dqLabel = idx === 0 ? '单位产品耗用原材料数量' : `单位产品耗用原材料数量${idx+1}`
      const umLabel = idx === 0 ? '材料单价' : `材料单价${idx+1}`
      return `${dqLabel}*${umLabel}`
    })
    // 替换 单位产品耗用原材料数量*材料单价 为 ∑（...）
    formula = formula.replace(/单位产品耗用原材料数量\s*\*\s*材料单价/g, `∑（${sumItems.join('，')}）`);
  }
  return formula;
});

// 拖拽相关
const formulaBoxPos = ref({ x: window.innerWidth - 900, y: 10 })
const dragging = ref(false)
const dragOffset = ref({ x: 0, y: 0 })

function onFormulaMouseDown(e) {
  dragging.value = true
  dragOffset.value = {
    x: e.clientX - formulaBoxPos.value.x,
    y: e.clientY - formulaBoxPos.value.y
  }
  document.addEventListener('mousemove', onFormulaMouseMove)
  document.addEventListener('mouseup', onFormulaMouseUp)
}
function onFormulaMouseMove(e) {
  if (!dragging.value) return
  formulaBoxPos.value = {
    x: e.clientX - dragOffset.value.x,
    y: e.clientY - dragOffset.value.y
  }
}
function onFormulaMouseUp() {
  dragging.value = false
  document.removeEventListener('mousemove', onFormulaMouseMove)
  document.removeEventListener('mouseup', onFormulaMouseUp)
}
</script>

<template>
  <div style="display: flex; gap: 24px;">
    <!-- 左侧树形菜单 -->
    <el-tree
      v-loading="treeLoading"
      :data="tree"
      node-key="parentId"
      :props="{ label: 'name', children: 'children' }"
      @node-click="handleNodeClick"
      style="width: 300px"
      highlight-current
      :default-expanded-keys="[0]"
    />
    <!-- 右侧内容区 -->
    <div style="flex: 1; position: relative;">
      <template v-if="selectedNode">
        <h3>
          {{ nodePath.slice(0, -1).join(' - ') }} - 【{{ nodePath[nodePath.length - 1] }}】税费计算
        </h3>
        <!-- 公式展示区域，右上角绝对定位 -->
        <div
          v-if="consumptionFormulaText || valueAddedFormulaText"
          :style="{
            position: 'absolute',
            top: formulaBoxPos.y + 'px',
            left: formulaBoxPos.x + 'px',
            width: '500px',
            minHeight: '120px',
            background: '#fff',
            border: '1px solid #eee',
            borderRadius: '8px',
            boxShadow: '0 2px 8px #0001',
            padding: '16px',
            zIndex: 2,
            cursor: dragging ? 'move' : 'grab',
            userSelect: 'none'
          }"
          @mousedown="onFormulaMouseDown"
        >
          <div v-if="consumptionFormulaText" style="margin-bottom: 12px;">
            <b>消费税公式：</b>
            <pre style="margin:0;white-space:pre-wrap;">{{ consumptionFormulaText }}</pre>
          </div>
          <div v-if="valueAddedFormulaText">
            <b>增值税公式：</b>
            <pre style="margin:0;white-space:pre-wrap;">{{ valueAddedFormulaText }}</pre>
          </div>
        </div>
        <el-form label-width="200px" style="max-width: 480px;">
          <el-form-item label="纳税人类型">
            <el-radio-group v-model="taxpayerType">
              <el-radio label="一般纳税人">一般纳税人</el-radio>
              <el-radio label="小规模纳税人">小规模纳税人</el-radio>
            </el-radio-group>
          </el-form-item>
          <template v-for="v in variables" :key="v.key">
            <el-form-item
              v-if="v.needAdd"
              :label="v.unit ? `${v.label}（${v.unit}）` : v.label"
            >
              <div style="width:100%">
                <div v-for="(val, idx) in inputVars[v.key]" :key="idx" style="display:flex;align-items:center;margin-bottom:4px;">
                  <el-input
                    v-model="inputVars[v.key][idx]"
                    type="number"
                    :placeholder="DOUBLE_ADD_KEYS.includes(v.key) ? `请输入${v.label}${idx > 0 ? idx+1 : ''}` : `请输入${v.label}`"
                  />
                  <!-- dq/um 的 - 号联动 -->
                  <el-button
                    v-if="DOUBLE_ADD_KEYS.includes(v.key) && inputVars[v.key].length > 1"
                    @click="handleDoubleRemove(idx)"
                    type="danger"
                    circle
                    size="small"
                    style="margin-left:4px;"
                  >
                    <el-icon><Minus /></el-icon>
                  </el-button>
                  <!-- 其他 needAdd 字段的 - 号 -->
                  <el-button
                    v-else-if="inputVars[v.key].length > 1"
                    @click="handleRemoveVar(v.key, idx)"
                    type="danger"
                    circle
                    size="small"
                    style="margin-left:4px;"
                  >
                    <el-icon><Minus /></el-icon>
                  </el-button>
                  <!-- 只在um行显示双加号，且两个字段都needAdd时 -->
                  <el-button
                    v-if="v.key === 'um' && showDoubleAddBtn() && idx === inputVars[v.key].length - 1"
                    @click="handleDoubleAdd"
                    type="primary"
                    circle
                    size="small"
                    style="margin-left:4px;"
                  >
                    <el-icon><Plus /></el-icon>
                  </el-button>
                  <!-- 其他needAdd字段的加号（不包括dq/um） -->
                  <el-button
                    v-else-if="v.needAdd && !DOUBLE_ADD_KEYS.includes(v.key) && idx === inputVars[v.key].length - 1"
                    @click="handleAddVar(v.key)"
                    type="primary"
                    circle
                    size="small"
                    style="margin-left:4px;"
                  >
                    <el-icon><Plus /></el-icon>
                  </el-button>
                </div>
              </div>
            </el-form-item>
            <el-form-item
              v-else
              :label="v.unit ? `${v.label}（${v.unit}）` : v.label"
            >
              <el-input
                v-model="inputVars[v.key]"
                type="number"
                :placeholder="`请输入${v.label}`"
              />
            </el-form-item>
          </template>
          <el-form-item label="单位成本">
            <el-input v-model="inputVars.cost" type="number" placeholder="请输入单位成本" />
          </el-form-item>
          <el-form-item label="地区">
            <el-select v-model="area" style="width: 100px">
              <el-option v-for="a in areaOptions" :key="a.value" :label="a.label" :value="a.value" />
            </el-select>
          </el-form-item>
          <el-form-item label="印花税类型">
            <el-select v-model="stampType" style="width: 200px">
              <el-option v-for="s in stampOptions" :key="s.value" :label="s.label" :value="s.value" />
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="calc">计算</el-button>
          </el-form-item>
        </el-form>
        <!-- 结果展示区域 -->
        <div v-if="result" style="margin-top: 24px;">
          <el-descriptions title="计算结果" :column="3" border>
            <el-descriptions-item label="税种/项目">公式</el-descriptions-item>
            <el-descriptions-item>带值公式</el-descriptions-item>
            <el-descriptions-item>结果</el-descriptions-item>
            <template v-for="item in resultFormulas" :key="item.label">
              <el-descriptions-item :label="item.label">{{ item.raw }}</el-descriptions-item>
              <el-descriptions-item>{{ item.val }}</el-descriptions-item>
              <el-descriptions-item>{{ item.result.toFixed(2) }}</el-descriptions-item>
            </template>
          </el-descriptions>
        </div>
      </template>
      <template v-else>
        <div class="welcome-card">
          <div class="welcome-title">欢迎使用多税种组合智能定价系统</div>
          <div class="welcome-desc">请选择左侧菜单进行计算</div>
        </div>
      </template>
    </div>
  </div>
</template>

<style scoped>
/* 布局整体美化 */
body, html {
  background: #f4f8fb;
}

:deep(.el-tree) {
  background: #fff;
  border-radius: 14px;
  box-shadow: 0 2px 16px #0001;
  padding: 18px 8px 18px 8px;
  min-height: 80vh;
  transition: box-shadow 0.3s;
}
:deep(.el-tree-node__content) {
  border-radius: 8px;
  transition: background 0.2s;
}
:deep(.el-tree-node__content:hover) {
  background: #eaf3ff;
}
:deep(.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content) {
  background: linear-gradient(90deg, #e0edff 0%, #f7fbff 100%);
  color: #409eff;
}
:deep(.el-tree)::-webkit-scrollbar {
  width: 8px;
  background: #f0f7ff;
  border-radius: 8px;
}
:deep(.el-tree)::-webkit-scrollbar-thumb {
  background: #dbeafe;
  border-radius: 8px;
}

/* 右侧内容区美化 */
.right-content-card {
  background: linear-gradient(135deg, #fafdff 0%, #f0f7ff 100%);
  border-radius: 18px;
  box-shadow: 0 4px 32px #0002;
  padding: 40px 36px 36px 36px;
  min-height: 80vh;
  position: relative;
  animation: fadeInUp 0.7s cubic-bezier(.39,.575,.565,1) both;
}
@keyframes fadeInUp {
  0% { opacity: 0; transform: translateY(40px); }
  100% { opacity: 1; transform: none; }
}

/* 欢迎卡片动画 */
.welcome-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 60vh;
  background: linear-gradient(135deg, #f0f7ff 0%, #e6ecfa 100%);
  border-radius: 16px;
  box-shadow: 0 4px 24px #0001;
  margin: 60px auto 0 auto;
  max-width: 600px;
  min-height: 300px;
  animation: fadeIn 1s;
}
@keyframes fadeIn {
  0% { opacity: 0; }
  100% { opacity: 1; }
}
.welcome-title {
  font-size: 2rem;
  font-weight: bold;
  color: #409eff;
  margin-bottom: 18px;
  letter-spacing: 2px;
}
.welcome-desc {
  font-size: 1.2rem;
  color: #666;
  letter-spacing: 1px;
}

/* 公式展示卡片美化 */
.formula-card {
  position: absolute;
  top: 50px;
  right: 50px;
  width: 500px;
  min-height: 120px;
  background: #fff;
  border: 1px solid #e3eaf5;
  border-radius: 12px;
  box-shadow: 0 2px 12px #0001;
  padding: 16px;
  z-index: 2;
  animation: fadeIn 0.7s;
}

/* 表单美化 */
:deep(.el-form) {
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 2px 12px #0001;
  padding: 24px 18px 18px 18px;
  margin-top: 18px;
  animation: fadeIn 0.7s;
}
:deep(.el-form-item__label) {
  color: #3a4a5b;
  font-weight: 500;
}
:deep(.el-input__inner), :deep(.el-select .el-input__inner) {
  border-radius: 8px;
  background: #f7fafd;
  transition: box-shadow 0.2s;
}
:deep(.el-input__inner:focus), :deep(.el-select .el-input__inner:focus) {
  box-shadow: 0 0 0 2px #a3d8ff44;
}
:deep(.el-radio.is-checked .el-radio__label) {
  color: #409eff;
}
:deep(.el-button--primary) {
  background: linear-gradient(90deg, #409eff 0%, #66b1ff 100%);
  border: none;
  border-radius: 8px;
  font-weight: bold;
  letter-spacing: 1px;
  transition: box-shadow 0.2s;
}
:deep(.el-button--primary:hover) {
  box-shadow: 0 2px 8px #409eff33;
}

/* 结果展示动画和美化 */
:deep(.el-descriptions) {
  background: #fafdff;
  border-radius: 12px;
  box-shadow: 0 2px 12px #0001;
  margin-top: 18px;
  animation: fadeInUp 0.7s;
}
:deep(.el-descriptions__title) {
  color: #409eff;
  font-size: 1.2rem;
  font-weight: bold;
}
:deep(.el-descriptions-item__label) {
  color: #3a4a5b;
  font-weight: 500;
}
:deep(.el-descriptions-item__content) {
  color: #1a2b3c;
  font-size: 1.1rem;
}

/* 响应式适配 */
@media (max-width: 900px) {
  .right-content-card {
    padding: 18px 4vw 18px 4vw;
    min-width: 0;
  }
  .formula-card {
    right: 10px;
    width: 90vw;
    min-width: 0;
  }
  .welcome-card {
    max-width: 95vw;
    min-width: 0;
  }
}
@media (max-width: 600px) {
  .right-content-card {
    padding: 8px 2vw 8px 2vw;
  }
  .formula-card {
    top: 10px;
    right: 0;
    left: 0;
    margin: 0 auto;
    width: 98vw;
  }
}
</style>
